#include <linux/memblock.h>
#include <linux/printk.h>
#include <linux/mm_init.h>
#include <linux/mmzone.h>
#include <linux/page_alloc.h>
#include <asm/page.h>
#include <linux/pfn.h>
#include <linux/mm.h>

#include <msh/export.h>
#include <stdlib.h>

extern void memblock_free_all(void);
extern void kmem_cache_init(void);
extern void build_all_zonelists_init(void);

static void initzone(void)
{
    unsigned long mzp[MAX_NR_ZONES] = {0};

    max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());

    mzp[ZONE_NORMAL] = PHYS_PFN(memblock_end_of_DRAM());
    free_area_init(mzp);
    build_all_zonelists_init();

    memblock_free_all();

    kmem_cache_init();
}
MSH_CMD_EXPORT(initzone, init zone);

static void apage(int argc, char **argv)
{
    struct page *pg;
    void *ptr;
    int cnt = 1;

    if (argc == 2)
    {
        cnt = atoi(argv[1]);
    }

    for (int i = 0; i < cnt; i++)
    {
        pg = __alloc_frozen_pages_noprof(0, 0, 0, NULL);
        ptr = pg ? page_address(pg) : NULL;

        printk("page[%d] %p, %p\n", i, pg, ptr);
    }
}
MSH_CMD_EXPORT(apage, alloc page);

static void afpage(int argc, char **argv)
{
    struct page *pg;
    int order = 0;

    if (argc == 2)
    {
        order = atoi(argv[1]);
    }

    pg = __alloc_frozen_pages_noprof(0, order, 0, NULL);
    if (pg)
        __free_pages(pg, order);

    printk("page %p\n", pg);
}
MSH_CMD_EXPORT(afpage, alloc and free page);
